package com.chainyoung.component_tmperson.ui.activity.dapp;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.chainyoung.common.appcommon.entity.HdFullWallet;
import com.chainyoung.common.appcommon.entity.HdWallet;
import com.chainyoung.common.appcommon.entity.HdWalletCache;
import com.chainyoung.common.appcommon.entity.HdWallets;
import com.chainyoung.common.appcommon.entity.WebTransactionInfo;
import com.chainyoung.common.appcommon.hdwallet.ExchangeCalculator;
import com.chainyoung.common.appcommon.hdwallet.OwnWalletUtils;
import com.chainyoung.common.appcommon.hdwallet.WalletStoreManger;
import com.chainyoung.common.constant.LibConstant;
import com.chainyoung.common.di.AppComponent;
import com.chainyoung.common.utils.CommonUtil;
import com.chainyoung.common.utils.SPUtil;
import com.chainyoung.common.utils.SystemUtils;
import com.chainyoung.common.utils.ToastUtil;
import com.chainyoung.component_tmperson.R;
import com.chainyoung.component_tmperson.di.component.DaggerPersonActivityComponent;
import com.chainyoung.component_tmperson.di.module.PersonActivityModule;
import com.chainyoung.component_tmperson.entity.BookMark;
import com.chainyoung.component_tmperson.entity.BrowseCache;
import com.chainyoung.component_tmperson.entity.CheckBookMarkResult;
import com.chainyoung.component_tmperson.ui.activity.dapp.BaseBrowserActivity;
import com.chainyoung.component_tmperson.ui.fragment.WebTransactionPayFragment;
import com.chainyoung.component_tmperson.ui.fragment.WebTransactionSetGasFragment;
import com.chainyoung.component_tmperson.ui.mvp.contract.OtheAppSendTransactionContract;
import com.chainyoung.component_tmperson.ui.mvp.presenter.OtherAppSendTransactionPresenter;
import com.chainyoung.router.RouterConstants;
import com.chainyoung.router.RouterUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.json.JSONException;
import org.spongycastle.util.encoders.Hex;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TreeMap;

import jnr.posix.LibC;

import static com.chainyoung.common.appcommon.hdwallet.CoinConstant.ETH;
import static com.chainyoung.common.appcommon.hdwallet.WalletServerConstant.CHAIN_ID;
import static com.chainyoung.common.constant.CommonStringConstants.URL;
import static com.chainyoung.component_tmperson.constant.PersonStringConstant.COIN_CN_NAME;
import static com.chainyoung.component_tmperson.constant.PersonStringConstant.COIN_NAME;
import static com.chainyoung.component_tmperson.constant.PersonStringConstant.ZC_FEE;
import static com.chainyoung.router.RouterConstants.PATH_OTHERAPP;


@Route(path = PATH_OTHERAPP)
public class BrowserActivity extends BaseBrowserActivity<OtherAppSendTransactionPresenter> implements OtheAppSendTransactionContract.View {


    private String title;


    //private List<HdWallet> walletList = new ArrayList<>();
    private List<HdWalletCache> walletList = new ArrayList<>();
    private HdWalletCache hdWalletCache;

    WebTransactionInfo webTransactionInfo;
    private WebTransactionPayFragment payFragment;
    private WebTransactionSetGasFragment setFragment;
    private BigDecimal oriGasPrice;//初始Gas price  单位Gwei
    private BigDecimal actualGasPrice;//用户实际Gas price 单位Gwei
    private BigDecimal actualOriGasLimit = BigDecimal.valueOf(700000);//gaslimit

    private String bookmarkId;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");


    @Override
    protected void setupActivityComponent(AppComponent appComponent) {
        DaggerPersonActivityComponent.builder()
                .appComponent(appComponent)
                .personActivityModule(new PersonActivityModule(this))
                .build()
                .inject(this);
    }

    @Override
    protected void initUI() {
        title = getIntent().getStringExtra("title");

        getWallets();

        /*HdWallets hdWallets = WalletStoreManger.getHdWallets();
        if (hdWallets == null) {
            ToastUtil.showToast("您未导入本地钱包，部分功能无法使用");
        } else {
            getWallets();
        }*/
        super.initUI();
        setEditTitle(title);

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        url = getIntent().getStringExtra(URL);
        if (!TextUtils.isEmpty(url)) {
            mWebView.loadUrl(url);
        }

    }

    private void getWallets() {
       /* HdWallets hdWallets = WalletStoreManger.getHdWallets();
        if (hdWallets != null && hdWallets.getWallets() != null && !hdWallets.getWallets().isEmpty()) {
            for (HdFullWallet hdFullWallet : hdWallets.getWallets()) {
                if (hdFullWallet.getCoinType().equals(ETH)) {
                    walletList.clear();
                    // TODO: 2018/9/6 此处以后扩展应该亦是每个币种的第一个钱包 或者是选中的默认钱包
                    walletList.add(hdFullWallet.getWallets().get(0));
                }
            }
        }
        if (!walletList.isEmpty()) {
            address = walletList.get(0).getAddress();
        }*/
        mPresenter.getAllHdWalletCaches(ETH);

    }


    @Override
    protected void initData() {

    }

    @Override
    protected int getLayoutId() {
        return super.getLayoutId();
    }


    //-----------------------------------------------------------点击事件---------------------------------------------------------------------------------

    @Override
    protected void checkUrlIsCollected(String url) {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("token", SPUtil.getString(LibConstant.TOKEN));
        map.put("url", url);
        mPresenter.checkIsUrlCollected(map);
    }

    @Override
    protected void cancelCollect() {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("token", SPUtil.getString(LibConstant.TOKEN));
        map.put("id", bookmarkId);
        mPresenter.delBookmark(map);
    }

    @Override
    protected void addCollect() {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("token", SPUtil.getString(LibConstant.TOKEN));
        map.put("title", webTitle);
        map.put("url", url);
        mPresenter.addBookmark(map);
    }

    @Override
    protected void addBrowseCache() {
        BrowseCache browseCache = new BrowseCache(webTitle, url, sdf.format(new Date(System.currentTimeMillis())), sdf1.format(new Date(System.currentTimeMillis())));
        mPresenter.addBrowseCache(browseCache);
    }


    //-----------------------------------------------------------以太坊Dapp 应用相关-----------------------------------------------------------------------

    /**
     * 交易信息
     *
     * @param transactionInfo
     */
    @Override
    protected void getWebTransactionInfo(String transactionInfo) {
        webTransactionInfo = new Gson().fromJson(transactionInfo, new TypeToken<WebTransactionInfo>() {
        }.getType());
        getGasPrice();
    }


    private void showPayFragment() {
        if (payFragment == null) {
            payFragment = new WebTransactionPayFragment();
        }


        String value = "0";
        if (TextUtils.isEmpty(webTransactionInfo.getObj().getValue())) {
            value = "0";
        } else if (webTransactionInfo.getObj().getValue().startsWith("0x")) {
            value = webTransactionInfo.getObj().getValue().substring(2);
        } else {
            value = webTransactionInfo.getObj().getValue();
        }

        payFragment.setNumAddr(new BigInteger(value
                , 16), webTransactionInfo.getObj().getTo(), hdWalletCache, actualGasPrice, actualOriGasLimit, webTitle);
        payFragment.show(getSupportFragmentManager(), "payFragment");
        payFragment.setIsCanceledTrade(true);
        payFragment.setOnOptionListener(new WebTransactionPayFragment.OptionListener() {
            @Override
            public void onAdjustFee(BigDecimal nowGasPrice, BigDecimal nowGasLimit) {
                //调节 gaslimit gasprice
                payFragment.close(false);
                showSettingFragment(nowGasPrice, nowGasLimit);
            }

            @Override
            public void onConfirmTrade() {
                getNonce();
            }

            @Override
            public void onCancelTrade(boolean isNeedDismiss) {
                if (isNeedDismiss) {
                    payFragment.dismiss();
                }
                //回调js callback 取消交易
                mWebView.loadUrl("javascript:executeCallback(8888,\"canceled\",null)");
            }
        });
    }


    private void showSettingFragment(BigDecimal nowGasPrice, BigDecimal nowGasLimit) {
        if (setFragment == null) {
            setFragment = new WebTransactionSetGasFragment();
        }
        setFragment.setData(oriGasPrice, nowGasPrice, nowGasLimit);
        setFragment.show(getSupportFragmentManager(), "payFragment");
        setFragment.setOnOptionListener(new WebTransactionSetGasFragment.OptionListener() {
            @Override
            public void onConfirmAdjust(BigDecimal gasPrice, BigDecimal gasLimit) {
                actualGasPrice = gasPrice;
                actualOriGasLimit = gasLimit;
                setFragment.dismiss();
                showPayFragment();
            }

            @Override
            public void onCancelJust(boolean isNeedDimiss) {
                if (isNeedDimiss) {
                    setFragment.dismiss();
                }
                showPayFragment();
            }
        });
    }


    //-------------------------------------------------------------浏览器相关------------------------------------------------------------
    @Override
    public void onCheckIsUrlCollected(CheckBookMarkResult result) {
        if (result == null) {
            ivCollect.setImageResource(R.mipmap.ic_browser_collect_no);
            return;
        }
        ivCollect.setImageResource(result.isIs_exists() ? R.mipmap.ic_browser_collected : R.mipmap.ic_browser_collect_no);
        isCollected = result.isIs_exists();
        bookmarkId = result.getId();
    }

    @Override
    public void onDelBookmarkSuccess(List<BookMark> data) {
        isCollected = false;
        ivCollect.setImageResource(R.mipmap.ic_browser_collect_no);
    }

    @Override
    public void onAddBookmarkSuccess(List<BookMark> data) {
        isCollected = true;
        ivCollect.setImageResource(R.mipmap.ic_browser_collected);
        for (BookMark bookMark : data) {
            if (bookMark.getUrl().equals(url)) {
                bookmarkId = bookMark.getId();
            }
        }
    }
    //-------------------------------------------------------------本地钱包-------------------------------------------------------------

    @Override
    public void onAddHdWalletCacheSuccess(HdWalletCache data) {

    }

    @Override
    public void onGetAllHdWalletCaches(List<HdWalletCache> datas) {
        walletList.clear();
        if (datas == null) {
            ToastUtil.showToast("您未导入本地钱包，部分功能无法使用");
            return;
        }
        walletList.addAll(datas);
        if (walletList.isEmpty()) {
            ToastUtil.showToast("您未导入本地钱包，部分功能无法使用");
            return;
        }
        hdWalletCache = walletList.get(0);
        address = hdWalletCache.getAddress();
    }




    //-------------------------------------------------------------以太坊请求-------------------------------------------------------------

    private void getGasPrice() {
        mPresenter.getGasPrice();
    }

    private void getNonce() {
        mPresenter.getNonce(address);
    }

    private void getWalletBalance(){
        mPresenter.getSingleEthBalance(address);
    }


    @Override
    public void onGetGasPriceSuccess(String data) {
        //为提升提交速率，默认gas price加2 Gwei
        BigInteger[] gasPriceGwei = new BigInteger(data.substring(2), 16).divideAndRemainder(new BigInteger(String.valueOf(1000000000)));
        String gasPriceStr = gasPriceGwei[0] + "." + gasPriceGwei[1];
        oriGasPrice = new BigDecimal(gasPriceStr).add(new BigDecimal(2)).setScale(2, RoundingMode.DOWN);
        actualGasPrice = oriGasPrice;
        showPayFragment();
    }

    @Override
    public void onGetNonce(String nonce) throws JSONException, CipherException, IOException {
        BigInteger tradeNonce = new BigInteger(nonce.substring(2), 16);
        String value = "0";
        if (TextUtils.isEmpty(webTransactionInfo.getObj().getValue())) {
            value = "0";
        } else if (webTransactionInfo.getObj().getValue().startsWith("0x")) {
            value = webTransactionInfo.getObj().getValue().substring(2);
        } else {
            value = webTransactionInfo.getObj().getValue();
        }
        RawTransaction tx = RawTransaction.createTransaction(
                tradeNonce,
                new BigInteger(String.valueOf(actualGasPrice.multiply(ExchangeCalculator.ONE_GWEI).setScale(0, RoundingMode.DOWN))),
                new BigInteger(String.valueOf(actualOriGasLimit)),
                webTransactionInfo.getObj().getTo(),
                new BigInteger(value, 16),
                webTransactionInfo.getObj().getData()
        );
        final Credentials keys = WalletStoreManger.getFullWallet(SPUtil.getString(LibConstant.PIN_CODE), OwnWalletUtils.getAccountFilePath(walletList.get(0)));
        byte[] signed = TransactionEncoder.signMessage(tx, (byte) CHAIN_ID, keys);

        mPresenter.sendTransaction("0x" + Hex.toHexString(signed));
    }

    @Override
    public void onSendTransactionSuccess(String hash) {
        if (payFragment != null) {
            payFragment.close(false);
        }
        ToastUtil.showToast("交易发送成功");
        //回调js callback
        mWebView.loadUrl("javascript:executeCallback(8888,null,\"成功\")");
        getWalletBalance();
    }

    @Override
    public void onSendTransactionFailed() {
        //回调js callback
        mWebView.loadUrl("javascript:executeCallback(8888,\"error\",null)");
    }


    @Override
    public void onGetSingleEthBalanceSuccess(String data, String addr) {
        if (new BigDecimal(data).compareTo(BigDecimal.ZERO) == 0) {
            hdWalletCache.setBalance("0");
        } else {
            hdWalletCache.setBalance(new BigDecimal(data).divide(ExchangeCalculator.ONE_ETHER, 8, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
        }
    }

    @Override
    public void onGetSingleEthBalanceFailed() {

    }



}
